home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / master / Examples / Visual / VOpts / state.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-01  |  15.7 KB  |  530 lines

  1. #include "vopts.h"
  2.  
  3. Prototype void handle_hit(struct Gadget *gad,int shift);
  4. Prototype void set_cyc_state(struct G_CYCLE *cyc,struct G_VALUE *val);
  5. Prototype void handle_list(struct G_LIST *list,struct Gadget *gad,int class);
  6. Prototype void redraw_gadget(struct Gadget *gad);
  7. Prototype void recalc_prop(struct G_LIST *list,UWORD *body,UWORD *sltop);
  8. Prototype void set_gadlist(struct GADLIST *gadlist,int state);
  9. Prototype void set_gadgets(int state);
  10.  
  11. /***********************************************************************************
  12.  * Procedure: handle_hit
  13.  * Synopsis:  handle_hit(gadget);
  14.  * Purpose:   Handle the processing for the hit on a gadget.
  15.  ***********************************************************************************/
  16. void handle_hit(struct Gadget *gad,
  17.                 int    shift
  18.                )
  19. {
  20.    struct G_OBJECT *obj;
  21.  
  22.    obj = (struct G_OBJECT *)gad->UserData;
  23.    /* Ignore any hits on disabled gadgets */
  24.    if ((gad->Flags & GADGHIGHBITS) == GADGHNONE) return;
  25.  
  26.    switch(gad->GadgetID)
  27.    {
  28.       case CLASS_CYCLE:
  29.          {
  30.             /* We need to advance the string to the next state */
  31.             /* When we refresh the gadget, we need to first blank it out */
  32.             struct G_CYCLE *cyc;
  33.             struct G_VALUE *val;
  34.  
  35.             cyc = (struct G_CYCLE *)obj;
  36.             val = cyc->curval;
  37.  
  38.             if (shift)
  39.             {
  40.                for(val = cyc->values;
  41.                    (val->next != NULL) && (val->next != cyc->curval);
  42.                    val = val->next);
  43.             }
  44.             else
  45.             {
  46.                val = val->next;
  47.                if (val == NULL) val = cyc->values;
  48.             }
  49.             set_cyc_state(cyc, val);
  50.          }
  51.          break;
  52.       case CLASS_CHECK:
  53.          obj->state = (gad->Flags & SELECTED) != 0;
  54.          break;
  55.       case CLASS_STRING:
  56.          {
  57.          struct StringInfo *si;
  58.          si = (struct StringInfo *)gad->SpecialInfo;
  59.          if ((si->Buffer[0]) || (obj->class != CLASS_LIST)) break;
  60.          }
  61.       case CLASS_DEL:
  62.       case CLASS_LIST:
  63.       case CLASS_LIST1:
  64.       case CLASS_LIST2:
  65.       case CLASS_ADD:
  66.       case CLASS_UP:
  67.       case CLASS_DOWN:
  68.       case CLASS_PROP:
  69.          handle_list((struct G_LIST *)obj, gad, gad->GadgetID);
  70.          break;
  71.       case CLASS_GROUP:
  72.          /* We need to advance to the next valid group */
  73.          {
  74.          int scope;
  75.          switch (global.filetype)
  76.          {
  77.             case FILE_OPTIONS:
  78.             case FILE_C:
  79.             case FILE_DMAKEFILE:
  80.                scope = 2;   /* note that global.filetype cannot == 2 */
  81.                break;
  82.             default:
  83.                /* FILE_ENV, uninitialized or whatever */
  84.                scope = 1;   /* to skip over non global options       */
  85.          }
  86.          do
  87.          {
  88.             if (shift)
  89.             {
  90.                global.curgroup = (struct G_GROUP *)global.curgroup->base.prev;
  91.                if (global.curgroup == NULL)
  92.                {
  93.                   global.curgroup = global.groups;
  94.                   while(global.curgroup->base.next != NULL)
  95.                      global.curgroup = (struct G_GROUP *)global.curgroup->base.next;
  96.                }
  97.             }
  98.             else
  99.             {
  100.                global.curgroup = (struct G_GROUP *)global.curgroup->base.next;
  101.                if (global.curgroup == NULL) global.curgroup = global.groups;
  102.             }
  103.          /* accept anything for options, c or dmakefile,  */
  104.          /* but only local for env                        */
  105.          } while (global.curgroup->local == scope);
  106.          set_group_gadgets();
  107.          break;
  108.          }
  109.       case CLASS_BUTTON:
  110.          switch(obj->state)
  111.          {
  112.             case BUTTON_SAVE:
  113.                /* Save the defaults permanently */
  114.                do_command("SAVE");
  115.                global.done = 1;
  116.                break;
  117.             case BUTTON_USE:
  118.                /* Use as the current defaults */
  119.                do_command("SAVE ENV");
  120.                global.done = 1;
  121.                break;
  122.             case BUTTON_CANCEL:
  123.                /* Just quit and don't do anything */
  124.                global.done = 1;
  125.                break;
  126.             case BUTTON_FRSAVE:
  127.             {
  128.                static char command[MAX_STRING+5];
  129.  
  130.                /* remove default file requester   */
  131.                clear_fr_gadgets();
  132.                /*copy string to global.filename and continue file operation */
  133.                strcpy(global.filename, global.frstring.buf);
  134.  
  135. #ifdef JGM_DBG
  136. printf("global.fileop = %ld\n", global.fileop);
  137. #endif
  138.                if (global.fileop == 0)   /* READ in progress */
  139.                   strcpy(command, "READ ");
  140.                else
  141.                {
  142.                   if (global.fileop == 1)
  143.                      strcpy(command, "SAVE ");
  144.                   else
  145.                      return;
  146.                }
  147. #ifdef JGM_DBG
  148. printf(">>%s<<\n", command);
  149. #endif
  150.                strcat(command, global.frstring.buf);
  151. #ifdef JGM_DBG
  152. printf(">>%s<<\n", command);
  153. #endif
  154.                global.nameoffile = 0; /* name may now be unsafe to write */
  155.                do_command(command);
  156.                break;
  157.             }
  158.             case BUTTON_FRCNCL:
  159.                /* clear file requester and do nothing */
  160.                clear_fr_gadgets();
  161.                break;
  162.          }
  163.          break;
  164.       default:
  165.          break;
  166.    }
  167. }
  168. /***********************************************************************************
  169.  * Procedure: redraw_gadget
  170.  * Synopsis:  redraw_gadget(gadget);
  171.  * Purpose:   Rerender a gadget on the screen
  172.  ***********************************************************************************/
  173. void redraw_gadget(struct Gadget *gad
  174.                   )
  175. {
  176.    SetBPen(global.rp, 0);
  177.    SetAPen(global.rp, 0);
  178.    RectFill( global.rp, gad->LeftEdge + VBAR, gad->TopEdge + HBAR,
  179.                          gad->LeftEdge + gad->Width - 1 - VBAR,
  180.                          gad->TopEdge + gad->Height - 1 - HBAR);
  181.    RefreshGList( gad, global.window, NULL, 1);
  182. }
  183.  
  184. /***********************************************************************************
  185.  * Procedure: set_cyc_state
  186.  * Synopsis:  set_cyc_state(cyc,val)
  187.  * Purpose:   Set a cycle gadget to a give value
  188.  ***********************************************************************************/
  189. void set_cyc_state(struct G_CYCLE *cyc,
  190.                    struct G_VALUE *val
  191.                   )
  192. {
  193.    struct G_STRING *str;
  194.    struct Gadget *gad;
  195.  
  196.    /* See It is currently being displayed on the screen.  If so, we will have to */
  197.    /* do some cleanup work to get it updated.                                    */
  198.    str = cyc->curval->string;
  199.    if ((str != NULL) && (str->base.gadget != NULL))
  200.    {
  201.       /* If there is a string gadget currently in the cycle gadget, we need */
  202.       /* to free it up                                                      */
  203.       RemoveGList( global.window, str->base.gadget, 1);
  204.       free_gadget(str->base.gadget);
  205.    }
  206.  
  207.    if (val == NULL) return;
  208.  
  209.    cyc->curval = val;
  210.  
  211.    /* Now, if we are currently displaying the gadget, we need to get it on the */
  212.    /* screen.                                                                  */
  213.    if (gad = cyc->base.gadget)
  214.    {
  215.       struct IntuiText *itext;
  216.       struct Gadget *strgad;
  217.       int oldpos;
  218.  
  219.       itext = gad->GadgetText->NextText;
  220.       itext->IText = val->title;
  221.  
  222.       strgad = setup_cycle_gadget(gad, itext, val);
  223.  
  224.       oldpos = RemoveGList(global.window, gad, 1);
  225.       AddGList(global.window, gad, oldpos, 1, NULL);
  226.  
  227.       if (strgad) AddGadget( global.window, strgad, 0);
  228.  
  229.       /* Wipe out the inner area of the gadget so that we can redraw it later */
  230.       redraw_gadget(gad);
  231.       if (strgad) redraw_gadget(strgad);
  232.    }
  233. }
  234.  
  235. /***********************************************************************************
  236.  * Procedure: handle_list
  237.  * Synopsis:  handle_list(list, gadget, int class);
  238.  * Purpose:   Handle the processing for the hit on a list gadget.
  239.  ***********************************************************************************/
  240. void handle_list(struct G_LIST *list,
  241.                  struct Gadget *gad,
  242.                  int class
  243.                 )
  244. {
  245.    struct G_ENTRY *ent, *prevent;
  246.    struct PropInfo *pi;
  247.    int expect;
  248.    int pos;
  249.    int i;
  250.    int oldpos[MAX_LIST];
  251.  
  252.    expect = 0;
  253.    if (list->string)
  254.    {
  255.       expect = 1;
  256.    }
  257.  
  258.    pos = list->base.state;
  259.  
  260.    switch(class)
  261.    {
  262.       case CLASS_LIST:
  263.       case CLASS_LIST1:
  264.       case CLASS_LIST2:
  265.          pos = class - CLASS_LIST;
  266.          expect = 1;
  267.          break;
  268.       case CLASS_ADD:
  269.          ent = get_mem(sizeof(struct G_ENTRY));
  270.          if (ent == NULL) return;
  271.          if (list->first == NULL)
  272.          {
  273.             int oldpos;
  274.             oldpos = RemoveGList(global.window, list->delgad, 1);
  275.             list->delgad->Flags   &= ~GADGDISABLED;
  276.             AddGList(global.window, list->delgad, oldpos, 1, NULL);
  277.             redraw_gadget(list->delgad);
  278.          }
  279.          prevent = list->top;
  280.          for (i = 0; (i < pos) && (prevent != NULL); i++)
  281.             prevent = (struct G_ENTRY *)prevent->base.next;
  282.          /* Insert in front of prevent */
  283.          ent->base.next = (struct G_OBJECT *)prevent;
  284.          if (prevent)
  285.          {
  286.             ent->base.prev = prevent->base.prev;
  287.             prevent->base.prev = (struct G_OBJECT *)ent;
  288.          }
  289.          if (ent->base.prev)
  290.          {
  291.             if (list->top == prevent) list->top = ent;
  292.             ent->base.prev->next = (struct G_OBJECT *)ent;
  293.          }
  294.          else
  295.          {
  296.             list->top = list->first = ent;
  297.          }
  298.          expect = 1;
  299.          break;
  300.       case CLASS_STRING:
  301.          {
  302.          struct StringInfo *si;
  303.          si = (struct StringInfo *)gad->SpecialInfo;
  304.          if (si->Buffer[0]) break;
  305.          }
  306.       case CLASS_DEL:
  307.          ent = list->top;
  308.          for (i = 0; (i < pos) && (ent != NULL); i++)
  309.             ent = (struct G_ENTRY *)ent->base.next;
  310.          /* We want to delete ent */
  311.          if (ent == NULL) return;
  312.          if (ent->base.next)
  313.             ent->base.next->prev = ent->base.prev;
  314.          if (ent->base.prev)
  315.             ent->base.prev->next = ent->base.next;
  316.          else
  317.             list->first = (struct G_ENTRY *)ent->base.next;
  318.  
  319.          /* Update the base pointer so that we are looking at the right space */
  320.          if (list->top == ent)
  321.          {
  322.             list->top = (struct G_ENTRY *)ent->base.next;
  323.             if (list->top == NULL)
  324.                list->top = (struct G_ENTRY *)ent->base.prev;
  325.          }
  326.          free_mem(ent, sizeof(struct G_ENTRY));
  327.       case CLASS_REFRESH:
  328.          {
  329.             int oldpos;
  330.  
  331.             expect = 0;
  332.             oldpos = RemoveGList(global.window, list->delgad, 1);
  333.             if (list->first == NULL)
  334.                list->delgad->Flags   |=  GADGDISABLED;
  335.             else
  336.                list->delgad->Flags   &= ~GADGDISABLED;
  337.             AddGList(global.window, list->delgad, oldpos, 1, NULL);
  338.             redraw_gadget(list->delgad);
  339.          }
  340.          RefreshGList( list->delgad, global.window, NULL, 5);
  341.          break;
  342.       case CLASS_UP:
  343.          if ((list->top != NULL) && (list->top->base.prev != NULL))
  344.          {
  345.             list->top = (struct G_ENTRY *)list->top->base.prev;
  346.          }
  347.          break;
  348.       case CLASS_DOWN:
  349.          if ((list->top != NULL) && (list->top->base.next != NULL))
  350.          {
  351.             list->top = (struct G_ENTRY *)list->top->base.next;
  352.          }
  353.          break;
  354.       case CLASS_PROP:
  355.          pi = (struct PropInfo *)gad->SpecialInfo;
  356.          list->top = list->first;
  357.          i = (pi->VertPot*list->maxent)/MAXBODY;
  358.          if (i >= list->maxent) i = list->maxent - 1;
  359.          while((i > 0) && (list->top != NULL))
  360.          {
  361.             list->top = (struct G_ENTRY *)list->top->base.next;
  362.             i--;
  363.          }
  364.          if (list->top == NULL) list->top = list->first;
  365.          break;
  366.    }
  367.  
  368.    list->base.state = pos;
  369.  
  370.    gad = list->base.gadget;
  371.    list->string = 0;
  372.  
  373.    if (expect)
  374.    {
  375.       /* Make sure that we are actually in a position to enable the */
  376.       /* requested string gadget.  If not, just ignore the request  */
  377.       ent = list->top;
  378.       for(i = pos; ent && (i > 0); i--)
  379.          ent = (struct G_ENTRY *)ent->base.next;
  380.  
  381.       if (ent)
  382.          list->string = 1;
  383.       else
  384.       {
  385.          pos = -1;
  386.          list->base.state = 0;
  387.       }
  388.    }
  389.    else
  390.    {
  391.       pos = -1;
  392.    }
  393.  
  394.    for(i = MAX_LIST-1; i >= 0; i--)
  395.    {
  396.       oldpos[i] = RemoveGList(global.window, list->btngad[i], 2);
  397.    }
  398.    reset_list_object(list, pos);
  399.  
  400.    /* Wipe out the inner area of the gadget so that we can redraw it later */
  401.    redraw_gadget(gad);
  402.  
  403.    for(i = 0; i < MAX_LIST; i++)
  404.    {
  405.       AddGList(global.window, list->btngad[i], oldpos[i], 2, NULL);
  406.       RefreshGList( list->btngad[i], global.window, NULL, 2);
  407.    }
  408.    if (pos >= 0)
  409.       ActivateGadget(list->strgad[pos], global.window, NULL);
  410.  
  411.    {
  412.       UWORD body, sltop;
  413.       recalc_prop(list, &body, &sltop);
  414.  
  415. #ifdef NewModifyProp
  416. #undef NewModifyProp
  417. #endif
  418.       NewModifyProp(list->slider, global.window, NULL,
  419.                     AUTOKNOB | FREEVERT | PROPBORDERLESS,
  420.                     0, sltop, MAXBODY, body, 1L);
  421.    }
  422. }
  423. /***********************************************************************************
  424.  * Procedure: recalc_prop
  425.  * Synopsis:  recalc_prop(list)
  426.  * Purpose:   Calculate the appropriate BODY and TOP values for a List Prop gadget
  427.  ***********************************************************************************/
  428. void recalc_prop(struct G_LIST *list,
  429.                  UWORD *body, UWORD *sltop
  430.                )
  431. {
  432.    int count, top;
  433.    struct G_ENTRY *ent;
  434.  
  435.    count = top = 0;
  436.    ent = list->first;
  437.  
  438.    while(ent != NULL)
  439.    {
  440.       if (ent == list->top) top = count;
  441.       count++;
  442.       ent = (struct G_ENTRY *)ent->base.next;
  443.    }
  444.  
  445.    list->maxent = count;
  446.  
  447.    *body  = MAXBODY;
  448.    *sltop = 0;
  449.    if (count > MAX_LIST)
  450.       *body  = (MAXBODY * MAX_LIST) / count;
  451.  
  452.    if (count)
  453.       *sltop = (MAXBODY * top     ) / count;
  454. }
  455. /***********************************************************************************
  456.  * Procedure: set_gadlist
  457.  * Synopsis:  set_gadlist(gadlist,on/off)
  458.  * Purpose:   Enable or Disable all the gadgets in a list
  459.  ***********************************************************************************/
  460. void set_gadlist(struct GADLIST *gadlist,
  461.                  int state
  462.                 )
  463. {
  464.    struct Gadget *gad;
  465.    struct G_CYCLE *cyc;
  466.    int count;
  467.  
  468.    if ((global.window == NULL) ||
  469.        (gadlist == NULL))
  470.       return;
  471.  
  472.    if (state)
  473.    {
  474. #ifdef AddGList
  475. #undef AddGList
  476. #endif
  477.       AddGList( global.window, gadlist->gadgets, 30000, gadlist->count, NULL);
  478.    }
  479.    else
  480.    {
  481.       RemoveGList(global.window, gadlist->gadgets, gadlist->count);
  482.    }
  483.  
  484.    for(gad = gadlist->gadgets, count=gadlist->count;
  485.        gad && count;
  486.        gad = gad->NextGadget, count--)
  487.    {
  488.       cyc = (struct G_CYCLE *)gad->UserData;
  489.  
  490.       if (cyc->base.class == CLASS_CYCLE)
  491.       {
  492.          set_cyc_state(cyc, state ? cyc->curval : NULL);
  493.       }
  494.       else if (state)
  495.       {
  496.          if (cyc->base.class == CLASS_LIST)
  497.          {
  498.             if (gad == cyc->base.gadget)
  499.                handle_list((struct G_LIST *)cyc, NULL, CLASS_REFRESH);
  500.          }
  501.          else
  502.          {
  503.         if (cyc->base.class == CLASS_CHECK)
  504.         {
  505.            if (cyc->base.state)
  506.            {
  507.           gad->Flags |= SELECTED;
  508.            }
  509.            else
  510.            {
  511.           gad->Flags &= ~SELECTED;
  512.            }
  513.         }
  514.              RefreshGList(gad, global.window, NULL, 1);
  515.          }
  516.       }
  517.    }
  518. }
  519.  
  520. /***********************************************************************************
  521.  * Procedure: set_gadgets
  522.  * Synopsis:  set_gadgets(on/off)
  523.  * Purpose:   Enable or Disable all gadgets
  524.  ***********************************************************************************/
  525. void set_gadgets(int state)
  526. {
  527.    set_gadlist(global.gadlist,    state);
  528.    set_gadlist(global.grpgadlist, state);
  529. }
  530.